
package src.uipackage.ui {
	
	import flash.display.Graphics;
	import flash.geom.Rectangle;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import src.uipackage.ui.events.ValueSliderEvent;
	import flash.display.Shape;
	import flash.display.LineScaleMode;
	import flash.display.CapsStyle;
	import flash.display.JointStyle;
	import flash.filters.DropShadowFilter;
	
	/**
	* UI widget that allows users to slide between specified minimum and maximum amounts.
	* @author Devon O.
	*/
	public class OBO_ValueSlider extends Sprite {
		
		private var _dragger:Sprite;
		private var _bar:Shape;
		private var _currentValue:Number;
		private var _bounds:Rectangle;
		private var _draggerClicked:Boolean;
		private var _max:Number;
		private var _min:Number;
		private var _maxX:Number;
		
		/**
		 * The OBO_ValueSlider class is a UI widget that creates a horizontal slider with an arrow that can be dragged to change the instance's value.
		 * When dragging the item's arrow, the class dispatches the com.onebyonedesign.ui.events.ValueSliderEvent.DRAG event.
		 * @example The following example creates an instance of OBO_ValueSlider and uses it to adjust the scaleX property of a Sprite.
		 * <listing version="3.0">
		 * private function initValueSlider():void {
		 *		var rect:Sprite = new Sprite();
		 *		rect.name = "rect";
		 *		rect.graphics.beginFill(0x232323);
		 *		rect.graphics.drawRect(0, 0, 200, 50);
		 *		rect.graphics.endFill();
		 *
		 *		addChild(rect);
		 *	
		 *		var vs:OBO_ValueSlider = new OBO_ValueSlider(200, 0, 1, 1);
		 *		vs.addEventListener(ValueSliderEvent.DRAG, onDrag);
		 *		vs.y = rect.y + rect.height + 20;
		 *		addChild(vs);
		 * }
		 * 
		 * private function onDrag(vse:ValueSliderEvent):void {
		 * 		vse.currentTarget.parent.getChildByName("rect").scaleX = vse.value;
		 * }
		 * </listing>
		 * @param	length			The length of the value slider
		 * @param	minValue		The minimum value of the slider
		 * @param	maxValue		The maximum value of the slider.
		 * @param	initialValue	The initial value of the slider.
		 */
		public function OBO_ValueSlider(length:Number, minValue:Number, maxValue:Number, initialValue:Number) {
			addEventListener(Event.ADDED_TO_STAGE, addedToStage, false, 0, true);
			
			_max = maxValue;
			_min = minValue;
			_currentValue = initialValue;
			
			_maxX = length - 7;
			
			_draggerClicked = false;
			_bounds = new Rectangle(0, 3, _maxX, 0);
			
			drawBar(length);
			addDragger();
		}
		
		private function addedToStage(e:Event):void {
			initDragger();
		}
		
		private function initDragger():void {
			_dragger.buttonMode = true;
			_dragger.useHandCursor = true;
			_dragger.addEventListener(MouseEvent.MOUSE_DOWN, onDown, false, 0, true);
			stage.addEventListener(MouseEvent.MOUSE_UP, onUp, false, 0, true);
		}
		
		private function onDown(me:MouseEvent):void {
			me.stopPropagation();
			_draggerClicked = true;
			_dragger.startDrag(false, _bounds);
			stage.addEventListener(MouseEvent.MOUSE_MOVE, onDrag, false, 0, true);
		}
		private function onUp(me:MouseEvent):void {
			if (_draggerClicked) {
				_draggerClicked = false;
				_dragger.stopDrag();
				//stage.removeEventListener(MouseEvent.MOUSE_MOVE, onDrag);
				dispatchEvent(new ValueSliderEvent(ValueSliderEvent.STOPDRAG, _currentValue));
			}
		}
		
		private function onDrag(me:MouseEvent):void {
			_currentValue = (_dragger.x / _maxX * (_max - _min)) + _min;
			me.updateAfterEvent();
			dispatchEvent(new ValueSliderEvent(ValueSliderEvent.DRAG, _currentValue));
		}
		
		private function drawBar(len:Number):void {
			_bar = new Shape();
			_bar.graphics.lineStyle(1, 0x959595, 1, true, LineScaleMode.NONE, CapsStyle.SQUARE, JointStyle.MITER, 1);
			_bar.graphics.moveTo(0, 0);
			_bar.graphics.lineTo(0, 2);
			_bar.graphics.lineTo(len, 2);
			_bar.graphics.lineTo(len, 0);
			addChild(_bar);
		}
		
		private function addDragger():void {
			_dragger = new Sprite();
			var g:Graphics = _dragger.graphics;
			g.lineStyle(1, 0x000000, 1, true, LineScaleMode.NONE, CapsStyle.SQUARE);
			g.beginFill(0xEEEEEE);
			g.moveTo(0, 0);
			g.lineTo( -5, 8);
			g.lineTo(5, 8);
			g.lineTo(0, 0);
			
			//_dragger.graphics.moveTo(3, 0);
			//_dragger.graphics.lineTo(4, 0);
			//_dragger.graphics.moveTo(2, 1);
			//_dragger.graphics.lineTo(5, 1);
			//_dragger.graphics.moveTo(1, 2);
			//_dragger.graphics.lineTo(6, 2);
			//_dragger.graphics.moveTo(0, 3);
			//_dragger.graphics.lineTo(7, 3);
			
			_dragger.x = ((_currentValue - _min) / (_max - _min)) * _maxX;
			_dragger.y = 3;
			_dragger.filters = [ new DropShadowFilter(2, 45, 0x000000, .6, 3, 3) ];
			addChild(_dragger);
		}
		
		public function get value():Number {
			return _currentValue;
		}
	}
}
